package com.storm.config

import com.fasterxml.jackson.databind.ObjectMapper
import com.storm.config.jackson.JacksonComponent
import com.storm.config.jackson.StormJackson2ObjectMapperBuilderCustomizer
import com.storm.config.jackson.StormJacksonProperties
import com.storm.config.rest.RestTemplateComponent
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.jackson.JacksonProperties
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cloud.client.loadbalancer.LoadBalanced
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary
import org.springframework.http.HttpRequest
import org.springframework.http.client.*
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
import org.springframework.web.client.RestTemplate

@Configuration
@EnableConfigurationProperties(JacksonProperties::class, StormJacksonProperties::class)
class ComponentAutoConfig {
    @Bean
    fun jackson2ObjectMapperBuilder(applicationContext: ApplicationContext, jacksonProperties: JacksonProperties, stormJacksonProperties: StormJacksonProperties): Jackson2ObjectMapperBuilder {
        val builder = Jackson2ObjectMapperBuilder.json()
        StormJackson2ObjectMapperBuilderCustomizer(applicationContext, jacksonProperties, stormJacksonProperties).customize(builder)
        builder.findModulesViaServiceLoader(true)
        return builder
    }

    /**
     * 自定义objectMapper
     */
    @Primary
    @Bean
    fun objectMapper(builder:Jackson2ObjectMapperBuilder): ObjectMapper {
        return builder.build()
    }

    /**
     * 实现简单的json转换操作
     */
    @Bean
    fun jacksonComponent(objectMapper: ObjectMapper): JacksonComponent {
        return JacksonComponent(objectMapper)
    }

    @Bean
    @LoadBalanced
    @ConditionalOnMissingBean(RestTemplate::class)
    fun restTemplate(): RestTemplate {
        val restTemplate = RestTemplate(simpleClientHttpRequestFactory())
        val headerInterceptor = HeaderInterceptor()
        headerInterceptor.setHeader("Accept","application/json")
        restTemplate.interceptors = listOf(headerInterceptor)
        return restTemplate
    }

    fun simpleClientHttpRequestFactory(): ClientHttpRequestFactory {
        val factory = SimpleClientHttpRequestFactory()
        //单位为ms
        factory.setReadTimeout(5000)
        //单位为ms
        factory.setConnectTimeout(5000)
        return factory
    }

    @Bean
    fun restTemplateComponent(restTemplate: RestTemplate):RestTemplateComponent{
        return RestTemplateComponent(restTemplate)
    }

}

class HeaderInterceptor:ClientHttpRequestInterceptor{

    private val map = HashMap<String, String>()

    fun setHeader(key: String, value: String) {
        map[key] = value
    }


    override fun intercept(request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution): ClientHttpResponse {
        map.forEach { (t, u) ->
            request.headers.set(t, u)
        }
        return execution.execute(request, body)
    }

}